#include "net.h"

void dandle(int* new)
{
	int newfd = *new;
	int ret;
    char buf[BUFSI];

	while(1)
	{
		//读
		bzero(buf, BUFSI);
		do
		{
			ret = read( newfd, buf, BUFSI-1);
		}while(ret < 0 && errno == EINTR);
		if(ret < 0)
		{
			perror("read");
			exit(1);
		}
		if(!ret )
		{
			break;	//用户以退出
		}
		printf("read: %s", buf);

	}
	close(newfd);
}

void quex(int sig)
{
	if(sig == SIGCHLD)
	{
		waitpid(-1, NULL, WNOHANG); 
	}
}

//===============================================
int main()
{

	int fd;
	struct sockaddr_in soc;

	signal(SIGCHLD, quex);

	//创建套接字
	if( ((fd = socket(AF_INET, SOCK_STREAM, 0 ))) < 0)
	{
		perror("socket");
		exit(1);
	}
	
	//快速重用
	int b_reuse = 1;
	setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof (int));


	//填充ip 和 端口号
	soc.sin_family = AF_INET;
	soc.sin_port = htons(POTR);
	soc.sin_addr.s_addr = htonl(INADDR_ANY);
	//绑定	
	if( (bind(fd, (struct sockaddr*)&soc, sizeof(soc))) < 0 )
	{
		perror("bind");
		exit(1);
	}

	//把主动变成被动
	if( (listen(fd, BACKLOG)) < 0)
	{
		perror("listen");
		exit(1);
	}
	printf("服务器启动成功\n");
	
	struct sockaddr_in sin;
	socklen_t addrlen = sizeof(sin);
	int newfd;
	while(1)
	{

		pid_t pid;
		//阻塞客户端连接
		if( (newfd = accept(fd, (struct sockaddr* )&sin, &addrlen)) < 0 )
		{

			perror("accept");
			break;
		}

		//创建进程处理
		
		if(pid = fork() < 0)
		{
			perror("fork");
			break;
		}
		if(pid == 0)
		{
			close(fd);
			char ip[16];
			//获取连接的客户端地址和端口号
			if( inet_ntop(AF_INET, (void* )&sin.sin_addr, ip, sizeof(sin))== NULL)
			{

				perror("inet_ntop");
				exit(1);
			}
			printf("client ip: %s port: %d\n", ip, ntohs(sin.sin_port));
			dandle(&newfd);

		}else
		{
			close(newfd);
		}
	}


	return 0;
}





















